【小ネタ】 監視カメラをPythonで操作してみました
1 はじめに
CX事業本部の平内(SIN)です。
店舗内の商品をComputerVisionで確認するために、前回、監視カメラをONVIFで操作してみました。
監視カメラには、専用の操作アプリがあり、その画面からカメラの操作は出来ます。
こちらは、ONVIFを無効化しても利用可能なので、どうやって操作をしているのか確認してみた所、簡単なHTTPで動作していることを確認できたので、今回は、それをラップするクラスを作ってみました。
2 監視カメラ
使用したのは、前回と同じ、ANRANの防犯カメラです。
https://www.amazon.co.jp/gp/product/B07VD693ND/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1
3 専用アプリ
専用アプリは、下記のような画面になっています。
左側の矢印ボタン等で、上下左右の回転や、ズームが可能になっています。
4 パケットモニタ
操作中のパケットをモニタすると、画面の画像についてはUDP、操作については、TCP(HTTP)で行われていることが分かります。
以下は、左回転の操作をした際の、TCPストリームを確認している様子です。
結果、カメラの動作は、以下のような、HTTPのGETだけで操作されていることが分かります。
左回転の操作開始
GET /web/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=left&-speed=45 HTTP/1.1 Host: 10.0.0.12 Connection: keep-alive Authorization: Basic YWRtaW46YWRtaW4= Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://10.0.0.12/web/mainpage.html Accept-Encoding: gzip, deflate Accept-Language: ja,en-US;q=0.9,en;q=0.8 HTTP/1.1 200 OK Server: Hipcam Cache-Control: no-cache Content-Type:text/html Connection: close Content-Length: 16 [Succeed]set ok.
左回転の操作停止
GET /web/cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act=stop&-speed=45 HTTP/1.1 Host: 10.0.0.12 Connection: keep-alive Authorization: Basic YWRtaW46YWRtaW4= Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://10.0.0.12/web/mainpage.html Accept-Encoding: gzip, deflate Accept-Language: ja,en-US;q=0.9,en;q=0.8 HTTP/1.1 200 OK Server: Hipcam Cache-Control: no-cache Content-Type:text/html Connection: close Content-Length: 16 [Succeed]set ok.
5 監視カメラ操作クラス
以下は、コマンド(GETリクエスト)を送って、UP, DOWN, RIGHT, LEFT, ZOOM及び、プリセットへの移動の操作を行うクラスです。 (speed=63は、最大スピードです)
cam.py
import requests from enum import Enum from time import sleep class Cmd(Enum): LET = 'left' RIGHT = 'right' UP = 'up' DOWN = 'down' IN = 'zoomin' OUT = 'zoomout' class Cam(): def __init__(self, host, user, password): self.__url = "http://{}:{}@{}/web/cgi-bin/hi3510/".format(user, password, host) self.__ptzctrl('stop') def ptz(self, cmd, sec): self.__ptzctrl(cmd.value) sleep(sec) self.__ptzctrl('stop') def preset(self, num): num = str(num - 1) requests.get("{}/preset.cgi?-act=goto&-number={}".format(self.__url, num)) def __ptzctrl(self, cmdStr): requests.get("{}/ptzctrl.cgi?-step=0&-act={}&-speed=63".format(self.__url, cmdStr))
上記のクラスを利用している例です。
index.py
from time import sleep from cam import Cam,Cmd # 防犯カメラ host = "10.0.0.12" user = "admin" password = "admin" cam = Cam(host, user, password) # コマンドの操作間隔(sec) WAIT = 3 while(True): print("プリセット50に移動") cam.preset(50) sleep(WAIT) print("ズームイン") cam.ptz(Cmd.IN, 3) sleep(WAIT) print("右へ移動") cam.ptz(Cmd.RIGHT, 0.5) sleep(WAIT) print("下へ移動") cam.ptz(Cmd.DOWN, 0.2) sleep(WAIT) print("ズームアウト") cam.ptz(Cmd.OUT, 2) sleep(WAIT) for i in range(6): print("プリセット{}に移動".Format(i+1)) cam.preset(i+1) sleep(WAIT)
6 最後に
今回は、監視カメラをHTTPで操作してみました。ONVIFで操作するより、非常にシンプルなコードになったかも知れません。